package dkbta.processing.data;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import dkbta.util.Log;

/**
 * Holds all of the information regarding the database, a connection to it and any
 * prepared statements
 * 
 * @author Uri Kanonov
 */
public class DB{
	private Connection _dbConn;

	private PreparedStatement _sendDataPS;

	private PreparedStatement _readDataPS;

	private final String _dbURL;

	private final String _dbDriver;

	private final String _dbUsername;

	private final String _dbPassword;

	private final String _inputTableName;

	private final String _outputTableName;

	public DB(String dbURL, String dbDriver, String dbUsername, String dbPassword,
		String inputTableName, String outputTableName){
		_dbURL = dbURL;
		_dbDriver = dbDriver;
		_dbUsername = dbUsername;
		_dbPassword = dbPassword;
		_inputTableName = inputTableName;
		_outputTableName = outputTableName;
	}

	public PreparedStatement getSendDataPS() throws SQLException{
		Connection conn;
		if (_outputTableName == null || (conn = getConnection()) == null){
			return null; // No output table name or connection
		}

		if (_sendDataPS == null){
			// SubjectID, ConceptName, StartTime, EndTime, ConceptValue, ConceptType
			_sendDataPS = conn.prepareStatement("INSERT INTO " + _outputTableName
					+ " VALUES(?,?,?,?,?,?, NULL)");
		}
		return _sendDataPS;
	}

	public PreparedStatement getReadDataPS() throws SQLException{
		Connection conn;
		if (_inputTableName == null || (conn = getConnection()) == null){
			return null; // No output table name or connection
		}

		if (_readDataPS == null){
			// SubjectID, FeatureName, StartTime, EndTime, FeatureValue
			_readDataPS = conn
					.prepareStatement("SELECT StartTime, EndTime, FeatureValue FROM "
							+ _inputTableName
							+ " WHERE SubjectID = ? AND FeatureName = ? ORDER BY StartTime ASC");
		}
		return _readDataPS;
	}

	public Connection getConnection() throws SQLException{
		if (_dbDriver == null){
			return null; // No DB Info set
		}
		try{
			if (_dbConn != null && !_dbConn.isClosed()){
				return _dbConn;
			}

			// Nullifying the statements
			_sendDataPS = null;
			_readDataPS = null;

			Class.forName(_dbDriver);
			_dbConn = DriverManager.getConnection(_dbURL, _dbUsername, _dbPassword);
		}catch(ClassNotFoundException e){
			Log.getLogger().warning(
				"Unable to load DB driver '" + _dbDriver
						+ "', make sure the JDBC jar is in the classpath: "
						+ e.getMessage());
			throw new SQLException("Unable to load DB driver '" + _dbDriver
					+ "', make sure the JDBC jar is in the classpath", e);
		}
		return _dbConn;
	}

	public void close(){
		System.out.println("Closing DB");
		try{
			if (_dbConn != null){
				_dbConn.close();
				if (_sendDataPS != null){
					_sendDataPS.close();
				}
			}
		}catch(SQLException e){
			Log.getLogger().warning("Unable to close DB", e);
		}
	}

	public String getInputTableName(){
		return _inputTableName;
	}

	@Override
	protected void finalize() throws Throwable{
		close();
	}
}
